﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Box2D.XNA;
using Imagine;

namespace Carmack
{
    /// <summary>
    /// WEAPON SYSTEM ///////////////////////////////////////////////////////
    /// </summary>
    public class CWeaponSystem
    {
        #region Private Members
        public CRangeWeapon m_primaryWeapon;
        public CRangeWeapon m_secondaryWeapon;
        public CRangeWeapon m_explosive;
        public CRangeWeapon m_heavyWeapon;
        public eWeaponClass m_currentWeaponClass;
        public eWeaponClass m_previousWeaponClass;
        public bool m_primaryEnable;
        public bool m_secondaryEnable;
        public bool m_explosiveEnable;
        public bool m_heavyWeaponEnable;
        public bool m_weaponSystemEnable;
        public CGameTimer m_weaponSwitchTimer;
        #endregion

        public CWeaponSystem( )
        {   
            m_primaryWeapon      = null;
            m_secondaryWeapon    = null;
            m_explosive          = null;
            m_heavyWeapon        = null;
            m_primaryEnable      = false;
            m_secondaryEnable    = false;
            m_explosiveEnable    = false;
            m_heavyWeaponEnable  = false;
            m_weaponSystemEnable = false;
            m_currentWeaponClass = eWeaponClass.NoWeapon;
            m_previousWeaponClass = eWeaponClass.NoWeapon;
            m_weaponSwitchTimer = new CGameTimer(2.5,0.7);
            m_weaponSwitchTimer.Start();
        }

        public void InitWeapon( CWeaponParams wParam, eWeaponClass wClass, string texture )
        {
            switch (wClass)
            {
            case eWeaponClass.Primary:      m_primaryWeapon = new CRangeWeapon( texture );
                                            m_primaryWeapon.Init( wParam );
                                            m_primaryEnable = true;      
                                            break;
            case eWeaponClass.Secondary:    m_secondaryWeapon = new CRangeWeapon( texture );
                                            m_secondaryWeapon.Init( wParam );
                                            m_secondaryEnable = true;
                                            break;
            case eWeaponClass.Explosive:    m_explosive = new CRangeWeapon( texture );
                                            m_explosive.Init( wParam );
                                            m_explosiveEnable = true;
                                            break;
            case eWeaponClass.HeavyWeapon:  m_heavyWeapon = new CRangeWeapon( texture );
                                            m_heavyWeapon.Init( wParam );    
                                            m_heavyWeaponEnable = true;  
                                            break;
            }
        }

        public bool IsWeaponAvailable( eWeaponClass weaponClass )
        {
            switch( weaponClass ) 
            {
             case eWeaponClass.Primary:     if( m_primaryEnable     )  { return true; }  break;
             case eWeaponClass.Secondary:   if( m_secondaryEnable   )  { return true; }  break;
             case eWeaponClass.Explosive:   if( m_explosiveEnable   )  { return true; }  break;
             case eWeaponClass.HeavyWeapon: if( m_heavyWeaponEnable )  { return true; }  break;
            }    
            return false;
        }

        public CWeapon GetWeapon(eWeaponClass weaponClass)
        {
            CWeapon weapon;
            if (IsWeaponAvailable(weaponClass))
            {
                eWeaponClass tempClass = m_currentWeaponClass;
                m_currentWeaponClass = weaponClass;
                GetCurrentWeapon(out weapon);
                m_currentWeaponClass = tempClass;
                return weapon;
            }
            return null;
        }

        public bool GetCurrentWeapon( out CWeapon weapon )
        {
            switch (m_currentWeaponClass)
            {
                case eWeaponClass.Primary:     if(m_primaryEnable)  {
                                                  weapon = m_primaryWeapon;
                                                  return true;
                                               }break;
                case eWeaponClass.Secondary:   if(m_secondaryEnable){
                                                  weapon = m_secondaryWeapon; 
                                                  return true;
                                               }break;
                case eWeaponClass.Explosive:   if(m_explosiveEnable){
                                                  weapon = m_explosive;
                                                  return true;
                                               }break;
                case eWeaponClass.HeavyWeapon: if(m_heavyWeaponEnable){
                                                 weapon = m_heavyWeapon; 
                                                 return true;
                                               }break;
            }
            weapon = null;
            return false;
        }

        public void SetWeaponFlag( eWeaponClass weaponClass, bool flag )
        {
            switch (weaponClass)
            {
             case eWeaponClass.Primary:     m_primaryEnable     = flag;  break;
             case eWeaponClass.Secondary:   m_secondaryEnable   = flag;  break;
             case eWeaponClass.Explosive:   m_explosiveEnable   = flag;  break;
             case eWeaponClass.HeavyWeapon: m_heavyWeaponEnable = flag;  break;
            }
        }

        public bool SetCurrentWeapon(eWeaponClass weaponClass)
        {
            // Check if the requested weapon is available
            if (!IsWeaponAvailable(weaponClass))
            {
                return false;
            }
            // It is already selected
            if (weaponClass == m_currentWeaponClass)
            {
                return true;
            }
            else // If not, then select it
            {
                m_previousWeaponClass = m_currentWeaponClass;
                m_currentWeaponClass = weaponClass;
                return true;
            }
        }

        protected void DebugRenderText(string str, Vector2 pos)
        {
            Engine.Instance().SpriteBatch.DrawString(  GameManager.Instance().SpriteFont, str, pos, Color.Aqua );
        }

        public void Update(GameTime gt_)
        {
            CWeapon weapon;
            if( GetCurrentWeapon(out weapon) ) 
                weapon.Update(gt_);
            m_weaponSwitchTimer.Update(gt_);
        }

        public void Draw(GameTime gt_)
        {
            CWeapon weapon;
            if( GetCurrentWeapon(out weapon) )
                weapon.Draw(gt_);
            
            Vector2 p1 = new Vector2(10,10);
            Vector2 p2 = new Vector2(28,10);
            Vector2 p3 = new Vector2(35,10);
            DebugRenderText(weapon.Bullets.ToString(), p1);
            DebugRenderText(" | " + weapon.RoundsLeft.ToString(), p2);
        }

        public CWeapon SwapWeapon(CWeapon newWeapon)
        {
            CWeapon prevWeapon = null;/*
            CWeapon XWeapon = null;
            bool IsActive = GetCurrentWeapon(out XWeapon);
            // If current weapon is available and its belongs to the same weapon class as of the newWeapon then Swap weapons
            if ( IsActive )
            {
                if( XWeapon.WeaponClass == newWeapon.WeaponClass )
                {
                    prevWeapon = XWeapon;
                    XWeapon = newWeapon;   // XWeapon is a reference to current weapon
                }
            }
            else
            {
            
            }

            else if( IsWeaponAvailable( newWeapon.WeaponClass ) )
            {
                m_previousWeaponClass = eWeaponClass.NoWeapon;
                m_currentWeaponClass  = newWeapon.WeaponClass;
                XWeapon = newWeapon;
            }
            */
            return prevWeapon;
        }

        public void ActivateNewWeapon( CWeapon weapon, bool enable )
        {
            
        }

        public void SwitchPrimarySecondary()
        {
            if( !IsWeaponSwitchable() ) return;

            if (m_currentWeaponClass == eWeaponClass.Primary || m_currentWeaponClass == eWeaponClass.Secondary) { 
            eWeaponClass classTp = ( m_currentWeaponClass == eWeaponClass.Primary ) 
                                                                ? eWeaponClass.Secondary : eWeaponClass.Primary;
                m_currentWeaponClass  = classTp;
                m_weaponSwitchTimer.Reset();
            }
        }

        public bool IsWeaponSwitchable()
        {
            return m_weaponSwitchTimer.IsFree();
        }

        public bool Fire( )
        {
            bool flag = false;
            CWeapon weapon;
            GetCurrentWeapon(out weapon);

            if ( weapon.Fire() )
            {
                flag = true;
                Vector2 vec = new Vector2( 20, 20 );
                Vector2 vec2 = vec * weapon.Direction;
                Vector2 vec3 = (weapon.Direction * new Vector2(27.0f, 27.0f)) + weapon.weaponSprite.Position; 
                CBullets bullet = new CBullets( "bullet", vec3 );
                //bullet.bulletSprite.Position = weapon.weaponSprite.Position+vec3;
                //bullet.bulletSprite.Position = vec3;
                bullet.Init();
                bullet.bulletSprite.Body.SetLinearVelocity( vec2 );
                TheWorld.Instance().Add( bullet, 1 );
            }
            return flag;
        }
    }

}
